package com.stay4it.rxjava;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.stay4it.rxjava.bean.Student;

import rx.Observable;
import rx.Subscriber;
import rx.functions.Action1;
import rx.functions.Action2;
import rx.functions.Func0;
import rx.functions.Func1;
import rx.functions.Func2;
import rx.observables.MathObservable;
import rx.schedulers.Schedulers;

/**
 * RxJava算术和聚合操作符
 * 
 * 算术操作符是属于可选的rxjava-math模块，需要单独下载jar包
 * http://search.maven.org/#search%7Cga%7C1%7Cio.reactivex.rxjava-math
 * 
 */
public class RxJava09 {

	/**
	 * average 
	 * 解释：计算原始Observable发射数字的平均值并发射它。
	 * Average操作符操作符一个发射数字的Observable，并发射单个值：原始Observable发射的数字序列的平均值。
	 * 
	 * 这个操作符不包含在RxJava核心模块中，它属于不同的rxjava-math模块。
	 * 它被实现为四个操作符：averageDouble, averageFloat, averageInteger, averageLong。
	 * 
	 * 算术操作符比较简单，容易理解。这里只做简单介绍。
	 */
	private static void test1() {
		MathObservable.averageInteger(Observable.just(1, 2, 3, 4))//  10/4=2
		.subscribe(new Action1<Integer>() {

			@Override
			public void call(Integer value) {
				System.out.println("onSuccess value = " + value);
			}
		});

	}

	/**
	 * 聚合操作符
	 * 
	 * concat 
	 * 解释：不交错的发射两个或多个Observable的数据。
	 */
	private static void test2() {
		Observable.concat(Observable.just(4,5,6),
				Observable.just("a","b","c")).subscribe(new Action1<Object>() {

					@Override
					public void call(Object value) {
						System.out.println("call value = " + value);
					}
				});
		
	}
	
	/**
	 * 聚合操作符
	 * 
	 * reduce 
	 * 解释：Reduce操作符应用一个函数接收Observable发射的数据和函数的计算结果作为下次计算的参数，输出最后的结果。
	 * 
	 * 注意如果原始Observable没有发射任何数据，reduce抛出异常IllegalArgumentException。 
	 * 
	 * 注：不建议使用reduce收集发射的数据到一个可变的数据结构，那种场景你应该使用collect。
	 */
	private static void test3() {
		
		Observable.just(1,2,3,4)
		.reduce(new Func2<Integer, Integer, Integer>() {
			//value1为前面几项的和，value2为当前发射的数据
			@Override
			public Integer call(Integer value1, Integer value2) {
				System.out.println("value1:"+value1+"  value2:"+value2);
				return value1 + value2;
			}
		})
		.subscribe(new Action1<Integer>() {
			
			@Override
			public void call(Integer value) {
				System.out.println("reduce value = " + value);
			}
		});
		
	}
	
	/**
	 * 聚合操作符
	 * 
	 * collect 
	 * 解释：将Observable的数据收集到一个数据结构中。
	 * 
	 * collect与reduce类似，但它的目的是收集原始Observable发射的所有数据到一个可变的数据结构，collect生成的这个Observable会发射这项数据。
	 */
	private static void test4() {
		
		Observable.just(0,1,2,3,4)
		.collect(new Func0<ArrayList<String>>() {

			@Override
			public ArrayList<String> call() {
				return new ArrayList<>();
			}
		}, new Action2<ArrayList<String>, Integer>() {

			@Override
			public void call(ArrayList<String> list, Integer value) {
				System.out.println("value = " + value);
				list.add(value + "");
			}
		})
		.subscribe(new Action1<ArrayList<String>>() {
			
			@Override
			public void call(ArrayList<String> list) {
				System.out.println("list.size() = " + list.size());
			}
		});
		
	}

	
	public static void main(String[] args) throws InterruptedException {
		test4();

	}

}
